package org.dzq.designmode.prototype;

import lombok.Data;
import org.dzq.designmode.prototype.bean.Student;

import java.io.*;

/**
 * @ClassName: DeepClonePrototype
 * @Package: org.dzq.designmode.prototype
 * @author: 越
 * @date: 2023/6/12 21:53
 * @Description:
 */
@Data
public class DeepClonePrototype implements Cloneable, Serializable {

    private static final long serialVersionUID = -1L;

    private String name;

    private int age;

    private Student student;

    /**
     * 方式1:重写clone方式
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected DeepClonePrototype clone() throws CloneNotSupportedException {
        DeepClonePrototype prototype = (DeepClonePrototype)super.clone();
        prototype.student= prototype.student==null ? null : student.clone();
        return prototype;
    }

    /**
     * 方式2:序列化对象方式(推荐)
     * @return
     */
    public DeepClonePrototype deepClone(){

        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            return (DeepClonePrototype)ois.readObject();
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("DeepClonePrototype.deepClone() is unexception error");
        }finally {
            try{
                if (ois != null) {
                    ois.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
            try{
                if (bis != null) {
                    bis.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
            try{
                if (oos != null) {
                    oos.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
            try{
                if (bos != null) {
                    bos.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}
